home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 23
/
AACD 23.iso
/
AACD
/
Online
/
opennap
/
userdb.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-06-08
|
5KB
|
261 lines
/* Copyright (C) 2000-1 drscholl@users.sourceforge.net
This is free software distributed under the terms of the
GNU Public License. See the file COPYING for details.
$Id: userdb.c,v 1.31 2001/02/15 08:39:45 drscholl Exp $ */
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <time.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <limits.h>
#include "opennap.h"
#include "debug.h"
HASH *User_Db = 0;
int
get_level (const char *s)
{
if (!strncasecmp ("lee", s, 3))
return LEVEL_LEECH;
if (!strncasecmp ("use", s, 3))
return LEVEL_USER;
if (!strncasecmp ("mod", s, 3))
return LEVEL_MODERATOR;
if (!strncasecmp ("eli", s, 3))
return LEVEL_ELITE;
if (!strncasecmp ("adm", s, 3))
return LEVEL_ADMIN;
return -1;
}
void
userdb_free (USERDB * p)
{
if (p)
{
if (p->nick)
FREE (p->nick);
#if EMAIL
if (p->email)
FREE (p->email);
#endif
if (p->password)
FREE (p->password);
FREE (p);
}
}
int
userdb_init (void)
{
FILE *fp;
int ac, regen = 0, level;
char *av[7], path[_POSIX_PATH_MAX];
USERDB *u;
snprintf (path, sizeof (path), "%s/users", Config_Dir);
fp = fopen (path, "r");
if (!fp)
{
logerr ("userdb_init", path);
return -1;
}
User_Db = hash_init (257, (hash_destroy) userdb_free);
log ("userdb_init(): reading %s", path);
if (fgets (Buf, sizeof (Buf), fp))
{
if (strncmp (":version 1", Buf, 10))
{
regen = 1;
rewind (fp);
}
}
while (fgets (Buf, sizeof (Buf), fp))
{
ac = split_line (av, FIELDS (av), Buf);
if (ac >= 6)
{
if (invalid_nick (av[0]))
{
log ("userdb_init(): %s: invalid nickname", av[0]);
continue;
}
u = CALLOC (1, sizeof (USERDB));
if (u)
{
u->nick = STRDUP (av[0]);
if (regen)
u->password = generate_pass (av[1]);
else
u->password = STRDUP (av[1]);
#if EMAIL
u->email = STRDUP (av[2]);
#endif
}
if (!u || !u->nick || !u->password
#if EMAIL
|| !u->email
#endif
)
{
OUTOFMEMORY ("userdb_init");
if (u)
userdb_free (u);
fclose (fp);
return -1;
}
level = get_level (av[3]);
if (level < 0 || level > LEVEL_ELITE)
{
log ("userdb_init(): invalid level %s for user %s", av[3],
u->nick);
level = LEVEL_USER;
}
u->level = level;
u->created = atol (av[4]);
u->lastSeen = atol (av[5]);
if (ac > 6)
u->flags = atoi (av[6]); /* u_short, atoi() is fine */
hash_add (User_Db, u->nick, u);
}
else
{
log ("userdb_init(): bad user db entry");
print_args (ac, av);
}
}
fclose (fp);
log ("userdb_init: %d registered users", User_Db->dbsize);
/* reformat to version 1 specification */
if (regen)
userdb_dump ();
return 0;
}
static void
dump_userdb (USERDB * db, FILE * fp)
{
if (global.current_time - db->lastSeen >= Nick_Expire)
{
if (db->level < LEVEL_MODERATOR)
{
strcpy (Buf, ctime (&db->lastSeen));
Buf[strlen (Buf) - 1] = 0;
log ("dump_userdb: %s has expired (last seen %s)", db->nick,
Buf);
hash_remove (User_Db, db->nick);
return;
}
/* warn, but dont nuke expired accounts for privileged users */
log ("dump_userdb: %s has expired (ignored: level=%s)",
db->nick, Levels[db->level]);
}
fputs (db->nick, fp);
fputc (' ', fp);
fputs (db->password, fp);
fputc (' ', fp);
#if EMAIL
fputs (db->email, fp);
#else
fputs ("unknown", fp); /* dummy value to keep file format the same */
#endif
fputc (' ', fp);
fputs (Levels[db->level], fp);
fputc (' ', fp);
fprintf (fp, "%d %u %hu", (int) db->created, (int) db->lastSeen,
db->flags);
#ifdef WIN32
fputs ("\r\n", fp);
#else
fputc ('\n', fp);
#endif
}
int
userdb_dump (void)
{
FILE *fp;
char path[_POSIX_PATH_MAX], tmppath[_POSIX_PATH_MAX];
log ("userdb_dump(): dumping user database");
snprintf (tmppath, sizeof (tmppath), "%s/users.tmp", Config_Dir);
fp = fopen (tmppath, "w");
if (!fp)
{
logerr ("userdb_dump", tmppath);
return -1;
}
#ifdef WIN32
fputs (":version 1\r\n", fp);
#else
fputs (":version 1\n", fp);
#endif
hash_foreach (User_Db, (hash_callback_t) dump_userdb, fp);
if (fflush (fp))
{
logerr ("userdb_dump", "fflush");
fclose (fp);
return -1;
}
if (fclose (fp))
{
logerr ("userdb_dump", "fclose");
return -1;
}
snprintf (path, sizeof (path), "%s/users", Config_Dir);
if (unlink (path))
logerr ("userdb_dump", "unlink"); /* not fatal, may not exist */
if (rename (tmppath, path))
{
logerr ("userdb_dump", "rename");
return -1;
}
log ("userdb_dump: wrote %d entries", User_Db->dbsize);
return 0;
}
/* create a default USERDB record from the existing user */
USERDB *
create_db (USER * user)
{
USERDB *db = CALLOC (1, sizeof (USERDB));
if (db)
{
db->nick = STRDUP (user->nick);
db->password = generate_pass (user->pass);
#if EMAIL
snprintf (Buf, sizeof (Buf), "anon@%s", Server_Name);
db->email = STRDUP (Buf);
#endif
db->level = user->level;
db->created = global.current_time;
db->lastSeen = global.current_time;
}
if (!db || !db->nick || !db->password
#if EMAIL
|| !db->email
#endif
)
{
OUTOFMEMORY ("create_db");
userdb_free (db);
return 0;
}
if (hash_add (User_Db, db->nick, db))
{
userdb_free (db);
return 0;
}
return db;
}